/*
 * f_engine.hpp
 *
 *  Created on: 09.03.2011
 *      Author: a.kubarkov
 */

#ifndef F_ENGINE_HPP_
# define F_ENGINE_HPP_

# include "misc/config.hpp"
# include "misc/barrier.hpp"
# include "core/type_info.hpp"
# include "system.hpp"

# include <boost/noncopyable.hpp>
# include <boost/shared_ptr.hpp>
# include <boost/cast.hpp>

# include <map>
# include <vector>

class f_engine_t : private boost::noncopyable
{
    typedef std::map<utils::type_info_t, if_system_t *> systems_map_t;
    typedef std::vector<boost::shared_ptr<if_system_t> > systems_creation_order_t;

public:

    f_engine_t();
    ~f_engine_t();

    void start();

    /* @brief Returns the interface of concrete system, contained in f_engine.*/
    template<typename SystemType>
    SystemType& system()
    {
        systems_map_t::iterator iter = systems_map_.find(typeid(SystemType));
        assert("Check that subsystem found" && systems_map_.end() != iter);
        assert("System already deleted" && iter->second);
        return *boost::polymorphic_downcast<SystemType *>(iter->second);
    }

    template<> config_t& system()
    {
        return config_;
    }

    /* @brief Systems synchronization functions.*/
    void report_started();
    void wait_all_systems();

private:

    template<typename SystemType>
    void add_system()
    {
        boost::shared_ptr<if_system_t> sys = SystemType::create(this);
        systems_map_[typeid(SystemType)] = sys.get();

        systems_creation_order_.push_back(sys);
    }

    systems_map_t systems_map_;
    systems_creation_order_t systems_creation_order_;

    config_t config_;

    boost::shared_ptr<barrier_t> system_started_barrier_;
};

#endif /* F_ENGINE_HPP_ */
